home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / quicktime / basics / addframetomovie / addframetomovie.c next >
Encoding:
Text File  |  2000-09-28  |  13.8 KB  |  592 lines

  1. /*
  2.     File:        AddFrameToMovie.c
  3.  
  4.     Contains:    Adding a Frame to the End of an Existing Movie.
  5.                 How To Test:
  6.                     Run the application, open a movie file, the application will now add an additional
  7.                     frame at the end of this existing movie.
  8.     Written by: John Wang    
  9.  
  10.     Copyright:    Copyright © 1991-1999 by Apple Computer, Inc., All Rights Reserved.
  11.  
  12.                 You may incorporate this Apple sample source code into your program(s) without
  13.                 restriction. This Apple sample source code has been provided "AS IS" and the
  14.                 responsibility for its operation is yours. You are not permitted to redistribute
  15.                 this Apple sample source code as "Apple sample source code" after having made
  16.                 changes. If you're going to re-distribute the source, we require that you make
  17.                 it clear in the source that the code was descended from Apple sample source
  18.                 code, but that you've made changes.
  19.  
  20.     Change History (most recent first):
  21.                 7/28/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  22.                 12/4/94        khs                changed the format of the file to the new look and feel
  23.                 94            JW                Fixed error where ind was assumed to be 0 based
  24.                                             rather than 1 based.  And, added code to update
  25.                                               movie rather than require a flatten movie for
  26.                                               saving the new edited movie.
  27. */
  28.  
  29. // INCLUDES
  30. #include     <GestaltEqu.h>
  31. #include    <Segload.h>
  32. #include    <ToolUtils.h>
  33. #include    <Devices.h>
  34. #include    <Errors.h>
  35.  
  36. #include    <Movies.h>
  37.  
  38.  
  39. // DEFINES
  40. #define Gestalttest        0xA1AD
  41. #define NoTrap            0xA89F
  42.  
  43. #define    appleID            128            
  44. #define    appleMenu        0
  45. #define    aboutMeCommand    1
  46.  
  47. #define    fileID            129
  48. #define openCommand        1
  49. #define    flattenCommand    2
  50. #define closeCommand    3
  51. #define    quitCommand     5
  52.  
  53. #define    aboutMeDLOG        128
  54. #define    okButton        1
  55.  
  56. #define    MAXWINDOWS        5
  57.  
  58. // FUNCTION PROTOTYPES
  59. Movie GetMovieFromFile(void);
  60. OSErr PlayMovie(int index);
  61. short Flatten(int index);
  62. void showAboutMeDialog(void);
  63. void Init(void);
  64. void Finish(void);
  65. void DoOpenCommand(void);
  66. void DoFlattenCommand(void);
  67. void DoCloseCommand(void);
  68. void PlayMovies(void);
  69. void DoCommand(long mResult);
  70.  
  71.  
  72. // GLOBALS
  73. Boolean DoneFlag = false;
  74. MenuHandle mymenu0, mymenu1;
  75. Boolean playingMovie[MAXWINDOWS];
  76. Movie myMovie[MAXWINDOWS];
  77. WindowPtr myWindow[MAXWINDOWS];
  78. int startlocation;
  79.  
  80.  
  81. // FUNCTIONS
  82.  
  83. /*------------------------------------------------------*/
  84. /*    GetMovieFromFile().                                    */
  85. /*------------------------------------------------------*/
  86.  
  87. Movie GetMovieFromFile(void)
  88. {
  89.     OSErr err;
  90.     StandardFileReply reply;
  91.     Point where =
  92.     {
  93.         200,  50
  94.     };
  95.     SFTypeList types;
  96.     short movieResRefNum;
  97.     short actualResId;
  98.     Movie theMovie;
  99.     long i,
  100.      maxCompressionSize;
  101.     Track myVideoTrack;
  102.     Media myVideoMedia;
  103.     OSType myMediaType;
  104.     Boolean done = false;
  105.     GWorldPtr myGWorld;
  106.     Rect movieBounds;
  107.     GDHandle oldGDevice;
  108.     CGrafPtr oldPort;
  109.     Handle compressedData;
  110.     ImageDescriptionHandle imageDescH;
  111.     TimeValue sampleDuration;
  112.     int x,y;
  113.  
  114.     types[0] = 'MooV';
  115.     StandardGetFilePreview(nil, 1, types, &reply);
  116.     if (!reply.sfGood)
  117.         return ((Movie)0);
  118.  
  119.     err = OpenMovieFile(&reply.sfFile, &movieResRefNum, fsWrPerm);
  120.     if (GetMoviesError())
  121.         return ((Movie)0);
  122.     if (err)
  123.         return ((Movie)0);
  124.     actualResId = 0;
  125.  
  126.     err = NewMovieFromFile(&theMovie, movieResRefNum, &actualResId, 
  127.                             (StringPtr)0, newMovieActive, (Boolean *)0);
  128.     if (GetMoviesError())
  129.         return ((Movie)0);
  130.     if (err)
  131.         return ((Movie)0);
  132.  
  133.     /*    This is where I add a frame to the end of the movie's video track.    */
  134.  
  135.     for (i = 1; ((i <= GetMovieTrackCount(theMovie)) && (!done)); i++)
  136.     {
  137.         myVideoTrack = GetMovieIndTrack(theMovie, i);
  138.         myVideoMedia = GetTrackMedia(myVideoTrack);
  139.         GetMediaHandlerDescription(myVideoMedia, &myMediaType, nil, nil);
  140.         if (myMediaType == VideoMediaType)
  141.             done = true;
  142.     }
  143.     if (done == false)
  144.         DebugStr("\pMovie contains no video tracks.");
  145.     else
  146.     {
  147.         if (BeginMediaEdits(myVideoMedia))
  148.             DebugStr("\pBeginMediaEdits failed.");
  149.  
  150.         GetMovieBox(theMovie, &movieBounds);
  151.         if (NewGWorld(&myGWorld, 1, &movieBounds, nil, nil, 0))
  152.             DebugStr("\pNewGWorld failed.");
  153.         GetGWorld(&oldPort, &oldGDevice);
  154.         SetGWorld(myGWorld, nil);
  155.         LockPixels(GetGWorldPixMap(myGWorld));
  156.         EraseRect(&movieBounds);
  157.         x=movieBounds.right/2;
  158.         y=movieBounds.bottom/2;
  159.         MoveTo(x, y);
  160.         DrawString("\pHi there");
  161.         imageDescH = (ImageDescriptionHandle)NewHandle(4);
  162.  
  163.         if (GetMaxCompressionSize(GetGWorldPixMap(myGWorld), &movieBounds, 1, 
  164.                                         codecNormalQuality, 'raw ', anyCodec, &maxCompressionSize))
  165.             DebugStr("\pCompressImage.");
  166.         compressedData = NewHandle(maxCompressionSize);
  167.         if (compressedData == nil)
  168.             DebugStr("\pCould not allocate compressedData block");
  169.         MoveHHi(compressedData);
  170.         HLock(compressedData);
  171.         if (CompressImage(GetGWorldPixMap(myGWorld), &movieBounds, codecNormalQuality, 
  172.                                 'raw ', imageDescH, StripAddress(*compressedData)))
  173.             DebugStr("\pCompressImage.");
  174.  
  175.         if (AddMediaSample(myVideoMedia, compressedData, 0, (**imageDescH).dataSize, 
  176.                             GetMediaTimeScale(myVideoMedia), (SampleDescriptionHandle)imageDescH, 
  177.                             1, 0, &sampleDuration))
  178.             DebugStr("\pInsertMediaIntoTracks.");
  179.  
  180.         if (InsertMediaIntoTrack(myVideoTrack, GetTrackDuration(myVideoTrack), sampleDuration, 
  181.                                     GetMediaTimeScale(myVideoMedia), 0x00010000))
  182.             DebugStr("\pInsertMediaIntoTracks.");
  183.  
  184.         if (EndMediaEdits(myVideoMedia))
  185.             DebugStr("\pEndMediaEdits failed.");
  186.         SetGWorld(oldPort, oldGDevice);
  187.         HUnlock(compressedData);
  188.         DisposeGWorld(myGWorld);
  189.         DisposeHandle(compressedData);
  190.         DisposeHandle((Handle)imageDescH);
  191.     }
  192.  
  193.     err = UpdateMovieResource(theMovie, movieResRefNum, actualResId, nil);
  194.     if (err != noErr)
  195.         DebugStr("\pUpdateResource failed.");
  196.  
  197.     /*    This is the end of the code for adding the one frame to the movie.    */
  198.  
  199.     err = CloseMovieFile(movieResRefNum);
  200.     if (GetMoviesError())
  201.         return ((Movie)0);
  202.     if (err)
  203.         return ((Movie)0);
  204.  
  205.     return (theMovie);
  206. }
  207.  
  208. /*------------------------------------------------------*/
  209. /*    PlayMovie().                                            */
  210. /*------------------------------------------------------*/
  211.  
  212. OSErr PlayMovie(int index)
  213. {
  214.     Rect movieBounds;
  215.  
  216.     GetMovieBox(myMovie[index], &movieBounds);
  217.     OffsetRect(&movieBounds, -movieBounds.left, -movieBounds.top);
  218.     if (movieBounds.right < 40)
  219.         movieBounds.right = 40;
  220.     if (movieBounds.bottom < 20)
  221.         movieBounds.bottom = 20;
  222.     SetMovieBox(myMovie[index], &movieBounds);
  223.     OffsetRect(&movieBounds, startlocation, startlocation);
  224.     myWindow[index] = NewCWindow(0L, &movieBounds, "\pMovie!", 1, 0, 
  225.                                     (WindowPtr) - 1, true, 0L);
  226.     startlocation += 50;
  227.     if (startlocation > 300)
  228.         startlocation = 50;
  229.  
  230.     SetMovieGWorld(myMovie[index], (CGrafPtr)myWindow[index], 0);
  231.     if (GetMoviesError())
  232.         DebugStr("\pSetMovieGWorld error.");
  233.  
  234.     /*    Uncomment these lines if you want to pre load the movie into ram.
  235.       GotoBeginningOfMovie(myMovie[index]);
  236.       if (LoadMovieIntoRam(myMovie[index], GetMovieTime(myMovie[index], 0L),
  237.       GetMovieDuration(myMovie[index]),
  238.       0) != noErr)
  239.       DebugStr("\pNot enough memory to load movie into ram.");
  240.     */
  241.     SetMovieRate(myMovie[index], 0x00010000);
  242.  
  243.     return noErr;
  244. }
  245.  
  246. /*------------------------------------------------------*/
  247. /*    Flatten().                                            */
  248. /*------------------------------------------------------*/
  249.  
  250. short Flatten(int index)
  251. {
  252.     StandardFileReply reply;
  253.     OSErr theErr = noErr;
  254.  
  255.     StandardPutFile("\pName of Flattened movie.", "\pUntitled", &reply);
  256.     if (!reply.sfGood)
  257.         return fnOpnErr;
  258.  
  259.     theErr = GetMoviesError();
  260.     if (theErr != noErr)
  261.         DebugStr("\pCall Before FlattenMovies failed.");
  262.  
  263.     FlattenMovie(myMovie[index], flattenAddMovieToDataFork, &reply.sfFile, 
  264.                         'TWOD', 0, createMovieFileDeleteCurFile, nil, nil);
  265.  
  266.     theErr = GetMoviesError();
  267.     if (theErr != noErr)
  268.         DebugStr("\pFlattenMovies failed.");
  269.  
  270.     return (theErr);
  271. }
  272.  
  273. /*------------------------------------------------------*/
  274. /*    showAboutMeDialog()                                    */
  275. /*------------------------------------------------------*/
  276.  
  277. void showAboutMeDialog(void)
  278. {
  279.     GrafPtr savePort;
  280.     DialogPtr theDialog;
  281.     short itemHit;
  282.  
  283.     GetPort(&savePort);
  284.     theDialog = GetNewDialog(aboutMeDLOG, nil, (WindowPtr) - 1);
  285.     SetPort(theDialog);
  286.  
  287.     do
  288.     {
  289.         ModalDialog(nil, &itemHit);
  290.     } while (itemHit != okButton);
  291.  
  292.     CloseDialog(theDialog);
  293.  
  294.     SetPort(savePort);
  295.     return;
  296. }
  297.  
  298. /*------------------------------------------------------*/
  299. /*    Init().                                                */
  300. /*------------------------------------------------------*/
  301.  
  302. void Init(void)
  303. {
  304.     OSErr err;
  305.     int i;
  306.     long QDfeature,
  307.      OSfeature;
  308.  
  309.     /*    Initialize Managaer.    */
  310.     InitGraf(&qd.thePort);
  311.     FlushEvents(everyEvent, 0);
  312.     InitWindows();
  313.     InitDialogs(nil);
  314.     InitCursor();
  315.  
  316.     /*    Set up menus.    */
  317.     mymenu0 = GetMenu(appleID);
  318.     AppendResMenu(mymenu0, 'DRVR');
  319.     InsertMenu(mymenu0, 0);
  320.     mymenu1 = GetMenu(fileID);
  321.     InsertMenu(mymenu1, 0);
  322.     DrawMenuBar();
  323.  
  324.     /*    Set up variables.    */
  325.     startlocation = 50;
  326.     for (i = 0; i < MAXWINDOWS; i++)
  327.     {
  328.         playingMovie[i] = false;
  329.         myWindow[i] = nil;
  330.     }
  331.  
  332.     /*    Use Gestalt to find if QuickDraw and QuickTime is available.    */
  333.     if ((NGetTrapAddress(Gestalttest,OSTrap) != NGetTrapAddress(NoTrap,OSTrap)))
  334.     {
  335.         err = Gestalt(gestaltQuickdrawVersion, &QDfeature);
  336.         if (err)
  337.             ExitToShell();
  338.         err = Gestalt(gestaltSystemVersion, &OSfeature);
  339.         if (err)
  340.             ExitToShell();
  341.         if (!DoneFlag && (QDfeature & 0x0f00) != 0x0200 && OSfeature < 0x0607)
  342.             ExitToShell();
  343.         err = Gestalt(gestaltQuickTime, &QDfeature);
  344.         if (err)
  345.             ExitToShell();
  346.     }
  347.     else
  348.         ExitToShell();
  349.  
  350.     /*    Open QuickTime last.    */
  351.     err = EnterMovies();
  352.     if (err)
  353.         ExitToShell();
  354. }
  355.  
  356. /*------------------------------------------------------*/
  357. /*    Finish().                                            */
  358. /*------------------------------------------------------*/
  359.  
  360. void Finish(void)
  361. {
  362.     ExitMovies();
  363.     ExitToShell();
  364. }
  365.  
  366. /*------------------------------------------------------*/
  367. /*    DoOpenCommand().                                        */
  368. /*------------------------------------------------------*/
  369.  
  370. void DoOpenCommand(void)
  371. {
  372.     int i,
  373.      useThisIndex;
  374.  
  375.     useThisIndex = -1;
  376.  
  377.     /*    Search for the first window that is nil.    */
  378.     for (i = MAXWINDOWS - 1; i >= 0; i--)
  379.         if (myWindow[i] == nil)
  380.             useThisIndex = i;
  381.  
  382.         /*    If index = -1, then it means that there are no windows avaiable.    */
  383.     if (useThisIndex != -1)
  384.     {
  385.         myMovie[useThisIndex] = GetMovieFromFile();
  386.         if (myMovie[useThisIndex] != 0)
  387.         {
  388.             PlayMovie(useThisIndex);
  389.             playingMovie[useThisIndex] = true;
  390.         }
  391.     }
  392. }
  393.  
  394. /*------------------------------------------------------*/
  395. /*    DoFlattenCommand().                                        */
  396. /*------------------------------------------------------*/
  397.  
  398. void DoFlattenCommand(void)
  399. {
  400.     int i;
  401.     WindowPtr myTempWindow;
  402.  
  403.     /*    Flatten movie that is currently selected.    */
  404.     myTempWindow = FrontWindow();
  405.     if (myTempWindow == nil)
  406.         return;
  407.     for (i = 0; i < MAXWINDOWS; i++)
  408.         if (myWindow[i] == myTempWindow)
  409.             Flatten(i);
  410. }
  411.  
  412. /*------------------------------------------------------*/
  413. /*    DoCloseCommand().                                        */
  414. /*------------------------------------------------------*/
  415.  
  416. void DoCloseCommand(void)
  417. {
  418.     int i;
  419.     WindowPtr myTempWindow;
  420.  
  421.     /*    Close selected window.    */
  422.     myTempWindow = FrontWindow();
  423.     if (myTempWindow == nil)
  424.         return;
  425.     for (i = 0; i < MAXWINDOWS; i++)
  426.         if (myWindow[i] == myTempWindow)
  427.         {
  428.             DisposeMovie(myMovie[i]);
  429.             DisposeWindow(myTempWindow);
  430.             playingMovie[i] = false;
  431.             myWindow[i] = nil;
  432.         }
  433. }
  434.  
  435. /*------------------------------------------------------*/
  436. /*    DoCommand().                                        */
  437. /*------------------------------------------------------*/
  438.  
  439. void DoCommand(long mResult)
  440. {
  441.     int theMenu,
  442.      theItem;
  443.     Str255 daName;
  444.     GrafPtr savePort;
  445.  
  446.     theItem = LoWord(mResult);
  447.     theMenu = HiWord(mResult);
  448.  
  449.     switch (theMenu)
  450.     {
  451.         case appleID:
  452.             if (theItem == aboutMeCommand)
  453.                 showAboutMeDialog();
  454.             else
  455.             {
  456.                 GetMenuItemText(mymenu0, theItem, daName);
  457.                 GetPort(&savePort);
  458.                 (void)OpenDeskAcc(daName);
  459.                 SetPort(savePort);
  460.             }
  461.             break;
  462.  
  463.         case fileID:
  464.             switch (theItem)
  465.             {
  466.                 case openCommand:
  467.                     DoOpenCommand();
  468.                     break;
  469.                 case flattenCommand:
  470.                     DoFlattenCommand();
  471.                     break;
  472.                 case closeCommand:
  473.                     DoCloseCommand();
  474.                     break;
  475.                 case quitCommand:
  476.                     DoneFlag = true;
  477.                     break;
  478.                 default:
  479.                     break;
  480.             }
  481.             break;
  482.     }
  483.     HiliteMenu(0);
  484.     return;
  485. }
  486.  
  487. /*------------------------------------------------------*/
  488. /*    PlayMovies().                                            */
  489. /*------------------------------------------------------*/
  490.  
  491. void PlayMovies(void)
  492. {
  493.     int i;
  494.  
  495.     for (i = 0; i < MAXWINDOWS; i++)
  496.         if (playingMovie[i] == true)
  497.         {
  498.             if (IsMovieDone(myMovie[i]) == false)
  499.                 MoviesTask(myMovie[i], DoTheRightThing);
  500.         }
  501. }
  502.  
  503. /*------------------------------------------------------*/
  504. /*    main().                                                */
  505. /*------------------------------------------------------*/
  506.  
  507. main()
  508. {
  509.     int i;
  510.     char key;
  511.     Boolean track;
  512.     EventRecord myEvent;
  513.     WindowPtr whichWindow;
  514.     int yieldTime;
  515.  
  516.  
  517.     Init();
  518.     yieldTime = 0;
  519.     for (;;)
  520.     {
  521.  
  522.         /*    We can't just do ExitToShell because we must cann ExitMovies.    */
  523.         if (DoneFlag)
  524.             Finish();
  525.  
  526.         /*    Play movies which are active.    */
  527.         PlayMovies();
  528.  
  529.         if (WaitNextEvent(everyEvent, &myEvent, yieldTime, nil))
  530.         {
  531.             switch (myEvent.what)
  532.             {
  533.                 case mouseDown:
  534.                     switch (FindWindow(myEvent.where, &whichWindow))
  535.                     {
  536.                         case inSysWindow:
  537.                             SystemClick(&myEvent, whichWindow);
  538.                             break;
  539.                         case inMenuBar:
  540.                             DoCommand(MenuSelect(myEvent.where));
  541.                             break;
  542.                         case inContent:
  543.                             SelectWindow(whichWindow);
  544.                             break;
  545.                         case inDrag:
  546.                             DragWindow(whichWindow, myEvent.where, &qd.screenBits.bounds);
  547.                             break;
  548.                         case inGrow:
  549.                             break;
  550.                         case inGoAway:
  551.                             track = TrackGoAway(whichWindow, myEvent.where);
  552.                             if (track)
  553.                                 DoCloseCommand();
  554.                             break;
  555.                         case inZoomIn:
  556.                             break;
  557.                         case inZoomOut:
  558.                             break;
  559.                         default:
  560.                             break;
  561.                     }
  562.                     break;
  563.                 case keyDown:
  564.                 case autoKey:
  565.                     key = myEvent.message & charCodeMask;
  566.                     if (myEvent.modifiers & cmdKey)
  567.                         if (myEvent.what == keyDown)
  568.                             DoCommand(MenuKey(key));
  569.                     break;
  570.                 case updateEvt:
  571.                     for (i = 0; i < MAXWINDOWS; i++)
  572.                         if ((WindowPtr)myEvent.message == myWindow[i])
  573.                         {
  574.                             BeginUpdate((WindowPtr)myWindow[i]);
  575.                             EndUpdate((WindowPtr)myWindow[i]);
  576.                         }
  577.                     break;
  578.                 case diskEvt:
  579.                     break;
  580.                 case activateEvt:
  581.                     break;
  582.                 case app4Evt:
  583.                     break;
  584.                 default:
  585.                     break;
  586.             }
  587.         }
  588.     }
  589. }
  590.  
  591.  
  592.